package com.kmzx.one.project.others.common;


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.converters.basic.BooleanConverter;
import com.thoughtworks.xstream.converters.basic.ByteConverter;
import com.thoughtworks.xstream.converters.basic.DateConverter;
import com.thoughtworks.xstream.converters.basic.DoubleConverter;
import com.thoughtworks.xstream.converters.basic.FloatConverter;
import com.thoughtworks.xstream.converters.basic.IntConverter;
import com.thoughtworks.xstream.converters.basic.LongConverter;
import com.thoughtworks.xstream.converters.basic.NullConverter;
import com.thoughtworks.xstream.converters.basic.ShortConverter;
import com.thoughtworks.xstream.converters.basic.StringConverter;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import com.thoughtworks.xstream.security.NoTypePermission;
import com.thoughtworks.xstream.security.WildcardTypePermission;

import java.io.Writer;

@XStreamAlias("xml")
public class WxSeaGateResponse {

    @XStreamAlias("return_code")
    private String return_code;
    @XStreamAlias("return_msg")
    private String return_msg;
    @XStreamAlias("sign_type")
    private String sign_type;
    @XStreamAlias("sign")
    private String sign;
    @XStreamAlias("appid")
    private String appid;
    @XStreamAlias("mch_id")
    private String mch_id;
    @XStreamAlias("result_code")
    private String result_code;
    @XStreamAlias("err_code")
    private String err_code;
    @XStreamAlias("err_code_des")
    private String err_code_des;
    @XStreamAlias("state")
    private String state;
    @XStreamAlias("transaction_id")
    private String transaction_id;
    @XStreamAlias("out_trade_no")
    private String out_trade_no;
    @XStreamAlias("sub_order_no")
    private String sub_order_no;
    @XStreamAlias("sub_order_id")
    private String sub_order_id;
    @XStreamAlias("modify_time")
    private String modify_time;
    @XStreamAlias("cert_check_result")
    private String cert_check_result;
    @XStreamAlias("verify_department")
    private String verify_department;
    @XStreamAlias("verify_department_trade_id")
    private String verify_department_trade_id;


    public String getReturn_code() {
        return return_code;
    }

    public WxSeaGateResponse setReturn_code(String return_code) {
        this.return_code = return_code;
        return this;
    }

    public String getReturn_msg() {
        return return_msg;
    }

    public WxSeaGateResponse setReturn_msg(String return_msg) {
        this.return_msg = return_msg;
        return this;
    }

    public String getSign_type() {
        return sign_type;
    }

    public WxSeaGateResponse setSign_type(String sign_type) {
        this.sign_type = sign_type;
        return this;
    }

    public String getSign() {
        return sign;
    }

    public WxSeaGateResponse setSign(String sign) {
        this.sign = sign;
        return this;
    }

    public String getAppid() {
        return appid;
    }

    public WxSeaGateResponse setAppid(String appid) {
        this.appid = appid;
        return this;
    }

    public String getMch_id() {
        return mch_id;
    }

    public WxSeaGateResponse setMch_id(String mch_id) {
        this.mch_id = mch_id;
        return this;
    }

    public String getResult_code() {
        return result_code;
    }

    public WxSeaGateResponse setResult_code(String result_code) {
        this.result_code = result_code;
        return this;
    }

    public String getErr_code() {
        return err_code;
    }

    public WxSeaGateResponse setErr_code(String err_code) {
        this.err_code = err_code;
        return this;
    }

    public String getErr_code_des() {
        return err_code_des;
    }

    public WxSeaGateResponse setErr_code_des(String err_code_des) {
        this.err_code_des = err_code_des;
        return this;
    }

    public String getState() {
        return state;
    }

    public WxSeaGateResponse setState(String state) {
        this.state = state;
        return this;
    }

    public String getTransaction_id() {
        return transaction_id;
    }

    public WxSeaGateResponse setTransaction_id(String transaction_id) {
        this.transaction_id = transaction_id;
        return this;
    }

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public WxSeaGateResponse setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
        return this;
    }

    public String getSub_order_no() {
        return sub_order_no;
    }

    public WxSeaGateResponse setSub_order_no(String sub_order_no) {
        this.sub_order_no = sub_order_no;
        return this;
    }

    public String getSub_order_id() {
        return sub_order_id;
    }

    public WxSeaGateResponse setSub_order_id(String sub_order_id) {
        this.sub_order_id = sub_order_id;
        return this;
    }

    public String getModify_time() {
        return modify_time;
    }

    public WxSeaGateResponse setModify_time(String modify_time) {
        this.modify_time = modify_time;
        return this;
    }

    public String getCert_check_result() {
        return cert_check_result;
    }

    public WxSeaGateResponse setCert_check_result(String cert_check_result) {
        this.cert_check_result = cert_check_result;
        return this;
    }

    public String getVerify_department() {
        return verify_department;
    }

    public WxSeaGateResponse setVerify_department(String verify_department) {
        this.verify_department = verify_department;
        return this;
    }

    public String getVerify_department_trade_id() {
        return verify_department_trade_id;
    }

    public WxSeaGateResponse setVerify_department_trade_id(String verify_department_trade_id) {
        this.verify_department_trade_id = verify_department_trade_id;
        return this;
    }

    public static WxSeaGateResponse fromXML(String xmlString) {
        XStream xstream = WxSeaGateResponse.getInstance();
        xstream.processAnnotations(WxSeaGateResponse.class);
        xstream.addPermission(AnyTypePermission.ANY);
        WxSeaGateResponse result = (WxSeaGateResponse) xstream.fromXML(xmlString);
        return result;
    }


    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("WxSeaGateResponse{");
        sb.append("return_code='").append(return_code).append('\'');
        sb.append(", return_msg='").append(return_msg).append('\'');
        sb.append(", sign_type='").append(sign_type).append('\'');
        sb.append(", sign='").append(sign).append('\'');
        sb.append(", appid='").append(appid).append('\'');
        sb.append(", mch_id='").append(mch_id).append('\'');
        sb.append(", result_code='").append(result_code).append('\'');
        sb.append(", err_code='").append(err_code).append('\'');
        sb.append(", err_code_des='").append(err_code_des).append('\'');
        sb.append(", state='").append(state).append('\'');
        sb.append(", transaction_id='").append(transaction_id).append('\'');
        sb.append(", out_trade_no='").append(out_trade_no).append('\'');
        sb.append(", sub_order_no='").append(sub_order_no).append('\'');
        sb.append(", sub_order_id='").append(sub_order_id).append('\'');
        sb.append(", modify_time='").append(modify_time).append('\'');
        sb.append(", cert_check_result='").append(cert_check_result).append('\'');
        sb.append(", verify_department='").append(verify_department).append('\'');
        sb.append(", verify_department_trade_id='").append(verify_department_trade_id).append('\'');
        sb.append('}');
        return sb.toString();
    }

    private static final XppDriver XPP_DRIVER = new XppDriver() {
        @Override
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out, getNameCoder()) {
                private static final String PREFIX_CDATA = "<![CDATA[";
                private static final String SUFFIX_CDATA = "]]>";
                private static final String PREFIX_MEDIA_ID = "<MediaId>";
                private static final String SUFFIX_MEDIA_ID = "</MediaId>";

                @Override
                protected void writeText(QuickWriter writer, String text) {
                    if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
                        writer.write(text);
                    } else if (text.startsWith(PREFIX_MEDIA_ID) && text.endsWith(SUFFIX_MEDIA_ID)) {
                        writer.write(text);
                    } else {
                        super.writeText(writer, text);
                    }

                }

                @Override
                public String encodeNode(String name) {
                    //防止将_转换成__
                    return name;
                }
            };
        }
    };

    public static XStream getInstance() {
        XStream xstream = new XStream(new PureJavaReflectionProvider(), XPP_DRIVER) {
            // only register the converters we need; other converters generate a private access warning in the console on Java9+...
            @Override
            protected void setupConverters() {
                registerConverter(new NullConverter(), PRIORITY_VERY_HIGH);
                registerConverter(new IntConverter(), PRIORITY_NORMAL);
                registerConverter(new FloatConverter(), PRIORITY_NORMAL);
                registerConverter(new DoubleConverter(), PRIORITY_NORMAL);
                registerConverter(new LongConverter(), PRIORITY_NORMAL);
                registerConverter(new ShortConverter(), PRIORITY_NORMAL);
                registerConverter(new BooleanConverter(), PRIORITY_NORMAL);
                registerConverter(new ByteConverter(), PRIORITY_NORMAL);
                registerConverter(new StringConverter(), PRIORITY_NORMAL);
                registerConverter(new DateConverter(), PRIORITY_NORMAL);
                registerConverter(new CollectionConverter(getMapper()), PRIORITY_NORMAL);
                registerConverter(new ReflectionConverter(getMapper(), getReflectionProvider()), PRIORITY_VERY_LOW);
            }
        };
        xstream.ignoreUnknownElements();
        xstream.setMode(XStream.NO_REFERENCES);
        XStream.setupDefaultSecurity(xstream);
        xstream.autodetectAnnotations(true);

        // setup proper security by limiting which classes can be loaded by XStream
        xstream.addPermission(NoTypePermission.NONE);
        xstream.addPermission(new WildcardTypePermission(new String[]{
                "me.chanjar.weixin.**", "cn.binarywang.wx.**", "com.github.binarywang.**", "com.kmzx.one.project.others.common.**"
        }));
        xstream.setClassLoader(Thread.currentThread().getContextClassLoader());
        return xstream;
    }
}
